/**
 * Copyright (c) 2015-2017, Henry Yang 杨勇 (gismail@foxmail.com).
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.mapfinal.portal;

import com.jfinal.config.Handlers;
import com.jfinal.config.Routes;
import com.jfinal.kit.StrKit;
import com.lambkit.Lambkit;
import com.lambkit.common.service.ServiceManager;
import com.lambkit.core.rpc.RpcConfig;
import com.lambkit.db.datasource.ActiveRecordPluginWrapper;
import com.lambkit.module.LambkitModule;
import com.lambkit.module.annotation.Module;
import com.mapfinal.gis.GisRoute;
import com.mapfinal.portal.PortalConfig;
import com.mapfinal.portal.controller.IndexController;
import com.mapfinal.portal.model.ActionLog;
import com.mapfinal.portal.model.Ad;
import com.mapfinal.portal.model.Article;
import com.mapfinal.portal.model.ArticleCategory;
import com.mapfinal.portal.model.ArticleCategoryMapping;
import com.mapfinal.portal.model.ArticleCategorySystemMapping;
import com.mapfinal.portal.model.ArticleCategoryTagMapping;
import com.mapfinal.portal.model.ArticleComment;
import com.mapfinal.portal.model.ArticleTagMapping;
import com.mapfinal.portal.model.Attachment;
import com.mapfinal.portal.model.Document;
import com.mapfinal.portal.model.Guestbook;
import com.mapfinal.portal.model.Links;
import com.mapfinal.portal.model.Menu;
import com.mapfinal.portal.model.MenuCat;
import com.mapfinal.portal.model.Option;
import com.mapfinal.portal.model.Plugins;
import com.mapfinal.portal.model.SinglePage;
import com.mapfinal.portal.model.Slide;
import com.mapfinal.portal.model.SlideCat;
import com.mapfinal.portal.model.System;
import com.mapfinal.portal.model.Tag;
import com.mapfinal.portal.model.WechatMenu;
import com.mapfinal.portal.model.WechatReply;
import com.mapfinal.portal.service.ActionLogService;
import com.mapfinal.portal.service.AdService;
import com.mapfinal.portal.service.ArticleService;
import com.mapfinal.portal.service.ArticleCategoryService;
import com.mapfinal.portal.service.ArticleCategoryMappingService;
import com.mapfinal.portal.service.ArticleCategorySystemMappingService;
import com.mapfinal.portal.service.ArticleCategoryTagMappingService;
import com.mapfinal.portal.service.ArticleCommentService;
import com.mapfinal.portal.service.ArticleTagMappingService;
import com.mapfinal.portal.service.AttachmentService;
import com.mapfinal.portal.service.DocumentService;
import com.mapfinal.portal.service.GuestbookService;
import com.mapfinal.portal.service.LinksService;
import com.mapfinal.portal.service.MenuService;
import com.mapfinal.portal.service.MenuCatService;
import com.mapfinal.portal.service.OptionService;
import com.mapfinal.portal.service.PluginsService;
import com.mapfinal.portal.service.SinglePageService;
import com.mapfinal.portal.service.SlideService;
import com.mapfinal.portal.service.SlideCatService;
import com.mapfinal.portal.service.SystemService;
import com.mapfinal.portal.service.TagService;
import com.mapfinal.portal.service.WechatMenuService;
import com.mapfinal.portal.service.WechatReplyService;
import com.mapfinal.portal.service.impl.ActionLogServiceImpl;
import com.mapfinal.portal.service.impl.ActionLogServiceMock;
import com.mapfinal.portal.service.impl.AdServiceImpl;
import com.mapfinal.portal.service.impl.AdServiceMock;
import com.mapfinal.portal.service.impl.ArticleServiceImpl;
import com.mapfinal.portal.service.impl.ArticleServiceMock;
import com.mapfinal.portal.service.impl.ArticleCategoryServiceImpl;
import com.mapfinal.portal.service.impl.ArticleCategoryServiceMock;
import com.mapfinal.portal.service.impl.ArticleCategoryMappingServiceImpl;
import com.mapfinal.portal.service.impl.ArticleCategoryMappingServiceMock;
import com.mapfinal.portal.service.impl.ArticleCategorySystemMappingServiceImpl;
import com.mapfinal.portal.service.impl.ArticleCategorySystemMappingServiceMock;
import com.mapfinal.portal.service.impl.ArticleCategoryTagMappingServiceImpl;
import com.mapfinal.portal.service.impl.ArticleCategoryTagMappingServiceMock;
import com.mapfinal.portal.service.impl.ArticleCommentServiceImpl;
import com.mapfinal.portal.service.impl.ArticleCommentServiceMock;
import com.mapfinal.portal.service.impl.ArticleTagMappingServiceImpl;
import com.mapfinal.portal.service.impl.ArticleTagMappingServiceMock;
import com.mapfinal.portal.service.impl.AttachmentServiceImpl;
import com.mapfinal.portal.service.impl.AttachmentServiceMock;
import com.mapfinal.portal.service.impl.DocumentServiceImpl;
import com.mapfinal.portal.service.impl.DocumentServiceMock;
import com.mapfinal.portal.service.impl.GuestbookServiceImpl;
import com.mapfinal.portal.service.impl.GuestbookServiceMock;
import com.mapfinal.portal.service.impl.LinksServiceImpl;
import com.mapfinal.portal.service.impl.LinksServiceMock;
import com.mapfinal.portal.service.impl.MenuServiceImpl;
import com.mapfinal.portal.service.impl.MenuServiceMock;
import com.mapfinal.portal.service.impl.MenuCatServiceImpl;
import com.mapfinal.portal.service.impl.MenuCatServiceMock;
import com.mapfinal.portal.service.impl.OptionServiceImpl;
import com.mapfinal.portal.service.impl.OptionServiceMock;
import com.mapfinal.portal.service.impl.PluginsServiceImpl;
import com.mapfinal.portal.service.impl.PluginsServiceMock;
import com.mapfinal.portal.service.impl.SinglePageServiceImpl;
import com.mapfinal.portal.service.impl.SinglePageServiceMock;
import com.mapfinal.portal.service.impl.SlideServiceImpl;
import com.mapfinal.portal.service.impl.SlideServiceMock;
import com.mapfinal.portal.service.impl.SlideCatServiceImpl;
import com.mapfinal.portal.service.impl.SlideCatServiceMock;
import com.mapfinal.portal.service.impl.SystemServiceImpl;
import com.mapfinal.portal.service.impl.SystemServiceMock;
import com.mapfinal.portal.service.impl.TagServiceImpl;
import com.mapfinal.portal.service.impl.TagServiceMock;
import com.mapfinal.portal.service.impl.WechatMenuServiceImpl;
import com.mapfinal.portal.service.impl.WechatMenuServiceMock;
import com.mapfinal.portal.service.impl.WechatReplyServiceImpl;
import com.mapfinal.portal.service.impl.WechatReplyServiceMock;
import com.mapfinal.portal.template.TemplateHandler;
import com.mapfinal.portal.web.tag.ActionLogDirective;
import com.mapfinal.portal.web.tag.AdDirective;
import com.mapfinal.portal.web.tag.ArticleDirective;
import com.mapfinal.portal.web.tag.ArticleCategoryDirective;
import com.mapfinal.portal.web.tag.ArticleCategoryMappingDirective;
import com.mapfinal.portal.web.tag.ArticleCategorySystemMappingDirective;
import com.mapfinal.portal.web.tag.ArticleCategoryTagMappingDirective;
import com.mapfinal.portal.web.tag.ArticleCommentDirective;
import com.mapfinal.portal.web.tag.ArticleTagMappingDirective;
import com.mapfinal.portal.web.tag.AttachmentDirective;
import com.mapfinal.portal.web.tag.DocumentDirective;
import com.mapfinal.portal.web.tag.GuestbookDirective;
import com.mapfinal.portal.web.tag.LinksDirective;
import com.mapfinal.portal.web.tag.MenuDirective;
import com.mapfinal.portal.web.tag.MenuCatDirective;
import com.mapfinal.portal.web.tag.OptionDirective;
import com.mapfinal.portal.web.tag.PluginsDirective;
import com.mapfinal.portal.web.tag.SinglePageDirective;
import com.mapfinal.portal.web.tag.SlideDirective;
import com.mapfinal.portal.web.tag.SlideCatDirective;
import com.mapfinal.portal.web.tag.SystemDirective;
import com.mapfinal.portal.web.tag.TagDirective;
import com.mapfinal.portal.web.tag.WechatMenuDirective;
import com.mapfinal.portal.web.tag.WechatReplyDirective;

/**
 * 门户系统
 * @author yangyong 
 * @website: www.lambkit.com
 * @email: gismail@foxmail.com
 * @date 2019-05-23
 * @version 1.0
 * @since 1.0
 */
@Module
public class PortalModule extends LambkitModule  {

	@Override
	public void configMapping(ActiveRecordPluginWrapper arp) {
		if(StrKit.isBlank(getConfig().getDbconfig())) {
			mapping(arp);
		}
	}
	
	@Override
	public void configMapping(String name, ActiveRecordPluginWrapper arp) {
		super.configMapping(name, arp);
		if(StrKit.notBlank(name) && name.equals(getConfig().getDbconfig())) {
			mapping(arp);
		}
	}
	
	@Override
	public void configRoute(Routes me) {
		me.add("/", IndexController.class);
		me.add(new ServiceRoute());
		me.add(new RestApiRoute());
		me.add(new GisRoute());
	}
	
	@Override
	public void configHandler(Handlers me) {
		me.add(new TemplateHandler("tpath"));
	}

	@Override
	public void onStart() {
		addTag(this);
		if("server".equals(getConfig().getDbconfig())) {
			registerLocalService();
		} else if("client".equals(getConfig().getDbconfig())) {
			registerRemoteService();
		} 
	}
	
	public void mapping(ActiveRecordPluginWrapper arp) {
		arp.addMapping("cms_action_log", "id", ActionLog.class);
		arp.addMapping("cms_ad", "id", Ad.class);
		arp.addMapping("cms_article", "id", Article.class);
		arp.addMapping("cms_article_category", "id", ArticleCategory.class);
		arp.addMapping("cms_article_category_mapping", "article_id,category_id", ArticleCategoryMapping.class);
		arp.addMapping("cms_article_category_system_mapping", "category_id,system_id", ArticleCategorySystemMapping.class);
		arp.addMapping("cms_article_category_tag_mapping", "category_id,tag_id", ArticleCategoryTagMapping.class);
		arp.addMapping("cms_article_comment", "id", ArticleComment.class);
		arp.addMapping("cms_article_tag_mapping", "article_id,tag_id", ArticleTagMapping.class);
		arp.addMapping("cms_attachment", "id", Attachment.class);
		arp.addMapping("cms_document", "id", Document.class);
		arp.addMapping("cms_guestbook", "id", Guestbook.class);
		arp.addMapping("cms_links", "id", Links.class);
		arp.addMapping("cms_menu", "id", Menu.class);
		arp.addMapping("cms_menu_cat", "id", MenuCat.class);
		arp.addMapping("cms_option", "id", Option.class);
		arp.addMapping("cms_plugins", "id", Plugins.class);
		arp.addMapping("cms_single_page", "id", SinglePage.class);
		arp.addMapping("cms_slide", "id", Slide.class);
		arp.addMapping("cms_slide_cat", "id", SlideCat.class);
		arp.addMapping("cms_system", "id", System.class);
		arp.addMapping("cms_tag", "id", Tag.class);
		arp.addMapping("cms_wechat_menu", "id", WechatMenu.class);
		arp.addMapping("cms_wechat_reply", "id", WechatReply.class);
	}
	
	public void addTag(LambkitModule lk) {
		lk.addTag("actionLog", new ActionLogDirective());
		lk.addTag("ad", new AdDirective());
		lk.addTag("article", new ArticleDirective());
		lk.addTag("articleCategory", new ArticleCategoryDirective());
		lk.addTag("articleCategoryMapping", new ArticleCategoryMappingDirective());
		lk.addTag("articleCategorySystemMapping", new ArticleCategorySystemMappingDirective());
		lk.addTag("articleCategoryTagMapping", new ArticleCategoryTagMappingDirective());
		lk.addTag("articleComment", new ArticleCommentDirective());
		lk.addTag("articleTagMapping", new ArticleTagMappingDirective());
		lk.addTag("attachment", new AttachmentDirective());
		lk.addTag("document", new DocumentDirective());
		lk.addTag("guestbook", new GuestbookDirective());
		lk.addTag("links", new LinksDirective());
		lk.addTag("menu", new MenuDirective());
		lk.addTag("menuCat", new MenuCatDirective());
		lk.addTag("option", new OptionDirective());
		lk.addTag("plugins", new PluginsDirective());
		lk.addTag("singlePage", new SinglePageDirective());
		lk.addTag("slide", new SlideDirective());
		lk.addTag("slideCat", new SlideCatDirective());
		lk.addTag("system", new SystemDirective());
		lk.addTag("tag", new TagDirective());
		lk.addTag("wechatMenu", new WechatMenuDirective());
		lk.addTag("wechatReply", new WechatReplyDirective());
	}
			
	public void registerLocalService() {
		registerLocalService(getRpcGroup(), getRpcVersion(), getRpcPort());
	}
	
	public void registerLocalService(String group, String version, int port) {
		ServiceManager.me().mapping(ActionLogService.class, ActionLogServiceImpl.class, ActionLogServiceMock.class, group, version, port);
		ServiceManager.me().mapping(AdService.class, AdServiceImpl.class, AdServiceMock.class, group, version, port);
		ServiceManager.me().mapping(ArticleService.class, ArticleServiceImpl.class, ArticleServiceMock.class, group, version, port);
		ServiceManager.me().mapping(ArticleCategoryService.class, ArticleCategoryServiceImpl.class, ArticleCategoryServiceMock.class, group, version, port);
		ServiceManager.me().mapping(ArticleCategoryMappingService.class, ArticleCategoryMappingServiceImpl.class, ArticleCategoryMappingServiceMock.class, group, version, port);
		ServiceManager.me().mapping(ArticleCategorySystemMappingService.class, ArticleCategorySystemMappingServiceImpl.class, ArticleCategorySystemMappingServiceMock.class, group, version, port);
		ServiceManager.me().mapping(ArticleCategoryTagMappingService.class, ArticleCategoryTagMappingServiceImpl.class, ArticleCategoryTagMappingServiceMock.class, group, version, port);
		ServiceManager.me().mapping(ArticleCommentService.class, ArticleCommentServiceImpl.class, ArticleCommentServiceMock.class, group, version, port);
		ServiceManager.me().mapping(ArticleTagMappingService.class, ArticleTagMappingServiceImpl.class, ArticleTagMappingServiceMock.class, group, version, port);
		ServiceManager.me().mapping(AttachmentService.class, AttachmentServiceImpl.class, AttachmentServiceMock.class, group, version, port);
		ServiceManager.me().mapping(DocumentService.class, DocumentServiceImpl.class, DocumentServiceMock.class, group, version, port);
		ServiceManager.me().mapping(GuestbookService.class, GuestbookServiceImpl.class, GuestbookServiceMock.class, group, version, port);
		ServiceManager.me().mapping(LinksService.class, LinksServiceImpl.class, LinksServiceMock.class, group, version, port);
		ServiceManager.me().mapping(MenuService.class, MenuServiceImpl.class, MenuServiceMock.class, group, version, port);
		ServiceManager.me().mapping(MenuCatService.class, MenuCatServiceImpl.class, MenuCatServiceMock.class, group, version, port);
		ServiceManager.me().mapping(OptionService.class, OptionServiceImpl.class, OptionServiceMock.class, group, version, port);
		ServiceManager.me().mapping(PluginsService.class, PluginsServiceImpl.class, PluginsServiceMock.class, group, version, port);
		ServiceManager.me().mapping(SinglePageService.class, SinglePageServiceImpl.class, SinglePageServiceMock.class, group, version, port);
		ServiceManager.me().mapping(SlideService.class, SlideServiceImpl.class, SlideServiceMock.class, group, version, port);
		ServiceManager.me().mapping(SlideCatService.class, SlideCatServiceImpl.class, SlideCatServiceMock.class, group, version, port);
		ServiceManager.me().mapping(SystemService.class, SystemServiceImpl.class, SystemServiceMock.class, group, version, port);
		ServiceManager.me().mapping(TagService.class, TagServiceImpl.class, TagServiceMock.class, group, version, port);
		ServiceManager.me().mapping(WechatMenuService.class, WechatMenuServiceImpl.class, WechatMenuServiceMock.class, group, version, port);
		ServiceManager.me().mapping(WechatReplyService.class, WechatReplyServiceImpl.class, WechatReplyServiceMock.class, group, version, port);
	}
	
	public void registerRemoteService() {
		registerRemoteService(getRpcGroup(), getRpcVersion(), getRpcPort());
	}
	
	public void registerRemoteService(String group, String version, int port) {
		ServiceManager.me().remote(ActionLogService.class, ActionLogServiceMock.class, group, version, port);
		ServiceManager.me().remote(AdService.class, AdServiceMock.class, group, version, port);
		ServiceManager.me().remote(ArticleService.class, ArticleServiceMock.class, group, version, port);
		ServiceManager.me().remote(ArticleCategoryService.class, ArticleCategoryServiceMock.class, group, version, port);
		ServiceManager.me().remote(ArticleCategoryMappingService.class, ArticleCategoryMappingServiceMock.class, group, version, port);
		ServiceManager.me().remote(ArticleCategorySystemMappingService.class, ArticleCategorySystemMappingServiceMock.class, group, version, port);
		ServiceManager.me().remote(ArticleCategoryTagMappingService.class, ArticleCategoryTagMappingServiceMock.class, group, version, port);
		ServiceManager.me().remote(ArticleCommentService.class, ArticleCommentServiceMock.class, group, version, port);
		ServiceManager.me().remote(ArticleTagMappingService.class, ArticleTagMappingServiceMock.class, group, version, port);
		ServiceManager.me().remote(AttachmentService.class, AttachmentServiceMock.class, group, version, port);
		ServiceManager.me().remote(DocumentService.class, DocumentServiceMock.class, group, version, port);
		ServiceManager.me().remote(GuestbookService.class, GuestbookServiceMock.class, group, version, port);
		ServiceManager.me().remote(LinksService.class, LinksServiceMock.class, group, version, port);
		ServiceManager.me().remote(MenuService.class, MenuServiceMock.class, group, version, port);
		ServiceManager.me().remote(MenuCatService.class, MenuCatServiceMock.class, group, version, port);
		ServiceManager.me().remote(OptionService.class, OptionServiceMock.class, group, version, port);
		ServiceManager.me().remote(PluginsService.class, PluginsServiceMock.class, group, version, port);
		ServiceManager.me().remote(SinglePageService.class, SinglePageServiceMock.class, group, version, port);
		ServiceManager.me().remote(SlideService.class, SlideServiceMock.class, group, version, port);
		ServiceManager.me().remote(SlideCatService.class, SlideCatServiceMock.class, group, version, port);
		ServiceManager.me().remote(SystemService.class, SystemServiceMock.class, group, version, port);
		ServiceManager.me().remote(TagService.class, TagServiceMock.class, group, version, port);
		ServiceManager.me().remote(WechatMenuService.class, WechatMenuServiceMock.class, group, version, port);
		ServiceManager.me().remote(WechatReplyService.class, WechatReplyServiceMock.class, group, version, port);
	}
	
	public int getRpcPort() {
		return Lambkit.config(RpcConfig.class).getDefaultPort();
	}
	public String getRpcGroup() {
		return Lambkit.config(RpcConfig.class).getDefaultGroup();
	}
	public String getRpcVersion() {
		return getConfig().getVersion();
	}
	public PortalConfig getConfig() {
		return Lambkit.config(PortalConfig.class);
	}
}

